#ifndef __DATA_H__
#define __DATA_H__
#include <qdebug.h>
#include <QDateTime>
#include <QIcon>
#include <QString>
#include <QUuid>
#include "..\Debug.h"
#include "base.qpb.h"
namespace model
{
////////////////////////////////////////////
/// \brief 工具类函数
////////////////////////////////////////////
/// @brief 获得当前时间戳的格式化时间 yyyy/MM/DD HH:mm
static inline QString get_formate_time(qint64 secs)
{
    QDateTime date_time = QDateTime::fromSecsSinceEpoch(secs);
    return date_time.toString("yyyy/MM/dd HH:mm");
}

/// @brief 获得当前的时间戳
static inline qint64 get_current_time_stamp()
{
    return QDateTime::currentSecsSinceEpoch();
}

/// @brief 将QByteArray转成QIcon
static inline QIcon make_icon(const QByteArray& content)
{
    QPixmap pixmap;
    pixmap.loadFromData(content);
    QIcon icon(pixmap);
    return icon;
}

/// @brief 读取文件内容
/// @return 是否读取成功
///     @retval "" 表示读取失败
///     @retval 不是上面的情况表示读取成功
static inline QByteArray read_file(const QString& file_name)
{
    QFile file(file_name);
    bool  ok = file.open(QIODevice::ReadOnly);
    if (ok == false) {
        LOG() << "open file: " << file_name << "error! why: " << file.errorString();
        return QByteArray();
        file.close();
    }
    QByteArray data = file.readAll();
    file.close();
    return data;
}

/// @brief 向文件中写数据
static inline bool write_file(const QString& file_name, const QByteArray& data)
{
    QFile file(file_name);
    bool  ok = file.open(QIODevice::WriteOnly);
    if (ok == false) {
        LOG() << "open file: " << file_name << "error! " << "why:" << file.errorString();
        return false;
        file.close();
    }
    ok = file.write(data);
    if (ok == false) {
        LOG() << "write file: " << file_name << "error!";
        return false;
        file.close();
    }
    file.flush();  // 刷新缓冲区
    file.close();
    return true;
}

////////////////////////////////////////////
/// \brief 用户信息类
////////////////////////////////////////////
class UserInfo
{
public:
    QString user_id     = "";  // 用户ID, oo号
    QString nick_name   = "";  // 用户昵称
    QString description = "";  // 个性签名
    QString phone_num   = "";  // 手机号
    QIcon   avatar;            // 头像

    /// @brief 将pb中的用户信息加载到UserInfo中
    void load(const chat::UserInfo& user_info)
    {
        user_id     = user_info.userId();
        nick_name   = user_info.nickname();
        description = user_info.description();
        phone_num   = user_info.phone();
        avatar      = make_icon(user_info.avatar());
    }
};

////////////////////////////////////////////
/// \brief 信息类
////////////////////////////////////////////
enum MessageType {
    TEXT_TYPE,
    IMAGE_TYPE,
    SPEECH_TYPE,
    FILE_TYPE,
    UNKNOW
};

class Message
{
public:
    MessageType message_type;          // 消息的类型
    QString     chat_session_id = "";  // 所对应的会话的id
    UserInfo    sender;                // 发送方
    QString     message_id = "";       // 消息id
    QString     time       = "";       // 发送该消息时格式化时间
    QByteArray  content;               // 内容取决于message_type
    QString     file_id   = "";        // 如果是图片, 文件, 语音类型, 表示对应的文件id, 不是就是""
    QString     file_name = "";        // 如果是文件消息, 表示文件名, 不是就是""
    /// @brief 创建消息的工厂方法
    /// @param extra_info被FILE_TYPE使用作为文件名
    static Message make_message_object(MessageType message_type, const QString& chat_session_id,
                                       const UserInfo& sender, const QByteArray& content,
                                       const QString extra_info)
    {
        if (message_type == TEXT_TYPE) {
            return make_text_message(chat_session_id, sender, content);
        } else if (message_type == IMAGE_TYPE) {
            return make_image_message(chat_session_id, sender, content);
        } else if (message_type == SPEECH_TYPE) {
            return make_speech_message(chat_session_id, sender, content);
        } else if (message_type == FILE_TYPE) {
            return make_file_message(chat_session_id, sender, content, extra_info);
        } else {
            LOG() << "Unknow Type!";
            return Message();
        }
    }
public:
    /// @brief 构造文本消息
    static Message make_text_message(const QString&  chat_session_id,
                                     const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        message.message_type    = TEXT_TYPE;
        message.chat_session_id = chat_session_id;
        message.sender          = sender;
        message.message_id      = make_id();
        message.time            = get_formate_time(get_current_time_stamp());
        message.content         = content;
        return message;
    }

    /// @brief 构造图片消息
    static Message make_image_message(const QString&  chat_session_id,
                                      const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        message.message_type    = IMAGE_TYPE;
        message.chat_session_id = chat_session_id;
        message.sender          = sender;
        message.message_id      = make_id();
        message.time            = get_formate_time(get_current_time_stamp());
        message.content         = content;
        return message;
    }

    /// @brief 构造语音消息
    static Message make_speech_message(const QString&  chat_session_id,
                                       const UserInfo& sender, const QByteArray& content)
    {
        Message message;
        message.message_type    = SPEECH_TYPE;
        message.chat_session_id = chat_session_id;
        message.sender          = sender;
        message.message_id      = make_id();
        message.time            = get_formate_time(get_current_time_stamp());
        message.content         = content;
        return message;
    }

    /// @brief 构造文件 消息
    static Message make_file_message(const QString&  chat_session_id,
                                     const UserInfo& sender, const QByteArray& content,
                                     const QString& extral_info)
    {
        Message message;
        message.message_type    = SPEECH_TYPE;
        message.chat_session_id = chat_session_id;
        message.sender          = sender;
        message.message_id      = make_id();
        message.time            = get_formate_time(get_current_time_stamp());
        message.file_name       = extral_info;
        message.content         = content;
        return message;
    }

    /// @brief 获得id
    static const QString make_id()
    {
        return "M-" + QUuid::createUuid().toString().sliced(25, 12);
        // return "";
    }

    /// @brief 将pb中的消息类型加载到Messages中
    void load(const chat::MessageInfo message_info)
    {
        message_id      = message_info.messageId();
        chat_session_id = message_info.chatSessionId();
        time            = get_formate_time(message_info.timestamp());
        sender.load(message_info.sender());
        auto type = message_info.message().messageType();
        switch (type) {
        case chat::MessageTypeGadget::MessageType::STRING: {
            message_type = TEXT_TYPE;
            content      = message_info.message().stringMessage().content().toUtf8();
            break;
        }
        case chat::MessageTypeGadget::MessageType::IMAGE: {
            if (message_info.message().msg_contentField() != chat::MessageContent::Msg_contentFields::ImageMessage) {
                LOG() << "MessageTypeGadget::MessageType::IMAGE, but msg_contentField is not ImageMessage!";
                return;
            }
            message_type            = IMAGE_TYPE;
            auto image_message_info = message_info.message().imageMessage();
            if (image_message_info.hasFileId()) {
                file_id = image_message_info.fileId();
            }
            if (image_message_info.hasImageContent()) {
                // 图片内容不一定存在(存疑??), 所以要判断一下
                content = image_message_info.imageContent();
            }
            break;
        }
        case chat::MessageTypeGadget::MessageType::FILE: {
            if (message_info.message().msg_contentField() != chat::MessageContent::Msg_contentFields::FileMessage) {
                LOG() << "MessageTypeGadget::MessageType::FILE, but msg_contentField is not FileMessage!";
                return;
            }
            message_type           = FILE_TYPE;
            auto file_message_info = message_info.message().fileMessage();
            if (file_message_info.hasFileId()) {
                file_id = file_message_info.fileId();
            }
            if (file_message_info.hasFileContents()) {
                content = file_message_info.fileContents();
            }
            file_name = file_message_info.fileName();
            break;
        }
        case chat::MessageTypeGadget::MessageType::SPEECH: {
            if (message_info.message().msg_contentField() != chat::MessageContent::Msg_contentFields::SpeechMessage) {
                LOG() << "MessageTypeGadget::MessageType::SPEECH, but msg_contentField is not SpeechMessage!";
                return;
            }
            message_type             = SPEECH_TYPE;
            auto speech_message_info = message_info.message().speechMessage();
            if (speech_message_info.hasFileId()) {
                file_id = speech_message_info.fileId();
            }
            if (speech_message_info.hasFileContents()) {
                content = speech_message_info.fileContents();
            }
            break;
        }
        default:
            LOG() << "Unknow message type: " << type;
            break;
        }
    }
};

////////////////////////////////////////////
/// \brief 聊天会话信息
////////////////////////////////////////////
class ChatSession
{
public:
    QString chat_session_id   = "";  // 会话id
    QString chat_session_name = "";  // 会话名称, 如果是群聊, 就是群名称, 如果是单聊, 就是好友名称
    Message prev_messsage;           // 上一条消息
    QString user_id;                 // 单聊时，表示对方的用户id，群聊时，字段为""
    QIcon   avatar;                  // 群聊头像框
    /// @brief 将pb中的会话类型加载到Messages中
    void load(const chat::ChatSessionInfo& chat_session_info)
    {
        chat_session_id   = chat_session_info.chatSessionId();
        chat_session_name = chat_session_info.chatSessionName();
        if (chat_session_info.hasPrevMessage()) {
            prev_messsage.load(chat_session_info.prevMessage());
            user_id = chat_session_info.prevMessage().sender().userId();
        }
        if (chat_session_info.hasAvatar()) {
            avatar = make_icon(chat_session_info.avatar());
        } else {
            /* 使用默认头像 */
            avatar = QIcon(":/image/defaultAvatar.png");
        }
    }
};
}  // namespace model

#endif
